﻿using System;
using System.Linq;
using System.Threading.Tasks;
using System.Transactions;
using Elsa.Services.Models;
using HengTong.Model;
using HengTong.Model._Admin;
using HengTong.Model.Db.Hr;
using HengTong.Model.Db.Hr.Bill;
using HengTong.Model.Db.System;
using HengTong.ViewModel._Admin.SysUserJobPositionVms;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using TiaoTaoHelper.Wtm.Interfaces;
using TiaoTaoHelper.Wtm.Models;
using TiaoTaoHelper.Wtm.Workflow;
using WalkingTec.Mvvm.Core;
using WalkingTec.Mvvm.Core.WorkFlow;

namespace HengTong.ViewModel.Hr.SysHrJobAssignmentRequestBillVms;

public partial class SysHrJobAssignmentRequestBillVm
{
    private ILogger<SysHrJobAssignmentRequestBillVm> _logger;

    [WorkflowOperation("驳回", "将单据状态设置为草稿", "岗位分配")]
    public async Task Reject(ActivityExecutionContext context)
    {
        Entity.BillStatus = BillStatus.草稿;
        if (Entity is IBasePoco poco)
        {
            poco.UpdateTime = DateTime.Now;
            DC.UpdateProperty(Entity, x => x.UpdateTime);
            if (context.Input is WtmApproveInput input)
            {
                poco.UpdateBy = input.CurrentUser?.ITCode ?? "workflow";
                DC.UpdateProperty(Entity, x => x.UpdateBy);
            }
        }

        DC.UpdateProperty(Entity, x => x.BillStatus);
        await DC.SaveChangesAsync();
    }

    [WorkflowOperation("取消", "将流程状态设置为取消", "岗位分配")]
    public async Task Cancel(ActivityExecutionContext context)
    {
        if (Entity is IBasePoco poco)
        {
            poco.UpdateTime = DateTime.Now;
            DC.UpdateProperty(Entity, x => x.UpdateTime);
            if (context.Input is WtmApproveInput input)
            {
                poco.UpdateBy = input.CurrentUser?.ITCode ?? "workflow";
                DC.UpdateProperty(Entity, x => x.UpdateBy);
            }
        }

        if (Entity is IBill bill)
        {
            bill.WorkflowStatus = WorkflowStatus.已取消;
            DC.UpdateProperty(Entity, x => x.WorkflowStatus);
        }

        await DC.SaveChangesAsync();
    }

    [WorkflowOperation("完成分配", "更新人员档案信息并设置为试用期", "岗位分配")]
    public async Task CompleteJobAssignment(ActivityExecutionContext context)
    {
        string currentUser = "workflow";
        if (context.Input is WtmApproveInput input)
        {
            currentUser = input.CurrentUser?.ITCode ?? "workflow";
        }

        // 在方法开始处获取 logger
        var scope = Wtm.ServiceProvider.CreateScope();
        _logger = scope.ServiceProvider.GetRequiredService<ILogger<SysHrJobAssignmentRequestBillVm>>();

        using var transactionScope = new TransactionScope(
            TransactionScopeOption.Required,
            new TransactionOptions
            {
                IsolationLevel = IsolationLevel.ReadCommitted,
                Timeout = TimeSpan.FromMinutes(5)
            },
            TransactionScopeAsyncFlowOption.Enabled);

        try
        {
            _logger.LogInformation("开始更新人员岗位信息，单据ID: {SourceBillId}, 操作人: {CurrentUser}, 时间: {Time}",
                Entity.ID, currentUser, DateTime.Now);

            // 获取分配明细
            var assignmentEntries = await DC.Set<SysHrJobAssignmentRequestBillEntry>()
                .Where(e => e.JobAssignmentId == Entity.ID)
                .AsNoTracking()
                .ToListAsync();

            if (!assignmentEntries.Any())
            {
                _logger.LogWarning("未找到岗位分配明细信息，单据编号: {BillCode}", Entity.BillCode);
                throw new Exception("未找到岗位分配明细信息");
            }

            foreach (var entry in assignmentEntries)
            {
                // 查找人员档案
                var targetPerson = await DC.Set<SysPerson>()
                    .Where(x => x.GetType() == typeof(SysPerson))
                    .FirstOrDefaultAsync(p => p.ID == entry.PersonId);

                if (targetPerson == null)
                {
                    _logger.LogError("未找到ID为 {PersonId} 的人员档案，终止岗位分配", entry.PersonId);
                    throw new Exception($"未找到ID为 {entry.PersonId} 的人员档案");
                }

                // 更新人员档案信息
                targetPerson.GroupId = entry.GroupId;
                targetPerson.OrgId = entry.OrgId;
                targetPerson.JobPositionId = entry.JobPositionId;
                targetPerson.State = PersonState.试用期; // 更新为试用期状态
                targetPerson.UpdateTime = DateTime.Now;
                targetPerson.UpdateBy = currentUser;

                DC.Set<SysPerson>().Update(targetPerson);

                // 查询并更新用户账号
                var user = await DC.Set<FrameworkUser>()
                    .FirstOrDefaultAsync(u => u.PersonId == targetPerson.ID);

                if (user != null)
                {
                    // 添加新岗位（有值才写入）
                    if (entry.JobPositionId.HasValue)
                    {
                        // 先删除原有的岗位信息
                        await DC.Set<SysUserJobPosition>()
                            .Where(e => e.UserId == user.ID)
                            .ExecuteDeleteAsync();

                        // 添加新的岗位信息
                        var newJobPosition = new SysUserJobPosition
                        {
                            UserId = user.ID,
                            JobPositionId = entry.JobPositionId.Value
                        };
                        await DC.Set<SysUserJobPosition>().AddAsync(newJobPosition);
                        await DC.SaveChangesAsync();

                        // 更新用户所属组
                        var jobPositionVm = new SysUserJobPositionVm
                        {
                            DC = this.DC,
                            Wtm = this.Wtm
                        };
                        await jobPositionVm.UpdateUserGroupAsync(user.ID);

                        // 刷新用户缓存
                        await Wtm.RemoveUserCache(user.ITCode);
                    }
                }
                else
                {
                    _logger.LogWarning("未找到工号为 {StaffNo} 的用户账号，跳过账号更新", targetPerson.StaffNo);
                }
            }

            // 更新单据状态
            Entity.WorkflowStatus = WorkflowStatus.已完成;
            DC.UpdateProperty(Entity, x => x.WorkflowStatus);

            await DC.SaveChangesAsync();
            transactionScope.Complete();

            _logger.LogInformation("成功完成岗位分配，单据ID: {BillId}", Entity.ID);
        }
        catch (Exception e)
        {
            _logger.LogError(e, "岗位分配完成操作失败，单据ID: {SourceBillId}, 操作人: {CurrentUser}, 时间: {Time}",
                Entity.ID, currentUser, DateTime.Now);
            MSD.AddModelError(" ", $"岗位分配完成操作失败: {e.Message}");
        }
    }
}